
#include "CoreEngine.h"
#include <assert.h>
#include <chrono>
#include <sstream>

#include "EngineManager.h"
#include "RenderEngine.h"
#include "../../CommonLib/src/ThreadHelper.h"


namespace FlameEngine
{
	CoreEngine::CoreEngine(char* cmdLine)
		:m_updateInterval(0),
		m_inited(false),
		m_frameCount(0),
		m_pEngineHelper(nullptr)
	{
		m_realTimer.Start_();

		m_logicTimer.EnableDebugAdjust(true);
		m_logicTimer.Start_();
	}

	CoreEngine::~CoreEngine()
	{
		delete m_pEngineHelper;
		m_pEngineHelper = nullptr;
	}

	void CoreEngine::Init(RenderEngine* pRenderEngine)
	{
		assert(pRenderEngine != nullptr && "RenderEngine is null!");

		m_pRenderEngine = pRenderEngine;

		m_inited = true;
	}

	void CoreEngine::StartRun()
	{
		m_engineThread = std::thread(&CoreEngine::Run, this);
	}

	void CoreEngine::Run()
	{		
		ThreadHelper::SetThreadName("Flame_Main");
		OnSystemStart();
		StartGameLoop();
	}

	void CoreEngine::StartGameLoop()
	{
		while(true)
		{
			double timePerFrame = 1.0 ;
			double timeErr = 0.001;
			UpdateTime();

			double elapsedTime = m_gameTime.GetElapsed();

			if(elapsedTime + timeErr > timePerFrame)
			{
				m_gameTime.ResetElapsedTime();
			}
			else
			{
				double delta = timePerFrame - elapsedTime;
				uint32_t milliseconds = (uint32_t)(delta * 1000);
				if(milliseconds > 0)
				{
					std::chrono::milliseconds timeToSleep(milliseconds);
					std::this_thread::sleep_for(timeToSleep);
				}
			}
		}
	}

	void CoreEngine::OnSystemStart()
	{

	}

	void CoreEngine::OnSystemShutdown()
	{
	}

	void CoreEngine::UpdateTime()
	{
		m_logicTimer.Update_();
		m_realTimer.Update_();

		double elapsed = m_realTimer.GetElapsedTime();
		double total = m_realTimer.GetTotalTime();
		double elapsedLogic = m_logicTimer.GetElapsedTime();
		double totalLogic = m_logicTimer.GetTotalTime();

		double curElapsed = m_gameTime.GetElapsed();
		double curElapsedLogic = m_gameTime.GetElapsedLogicTime();

		m_gameTime.SetTime_(curElapsed + elapsed, total,
			curElapsedLogic + elapsedLogic, totalLogic);
	}
}
